const path = require("path");
const fs = require("fs");
module.exports = class TestNow {
  // 默认路径就是当前文件夹
  genJestSource(sourcePath = path.resolve("./")) {
    const testPath = `${sourcePath}/__test__`;
    // 有__test__就不创建了没有就新建一个
    if (!fs.existsSync(testPath)) {
      fs.mkdirSync(testPath);
    }
    // 遍历代码文件
    let list = fs.readdirSync(sourcePath);
    // 添加完成路径 读取的只有文件名
    list
      .map((v) => `${sourcePath}/${v}`)
      // 过滤文件 只有文件夹被删除了
      .filter((v) => fs.statSync(v).isFile())
      // 排除测试代码
      // indexOf() 方法可返回某个指定的字符串值在字符串中首次出现的位置
      // -1表示没有出现
      .filter((v) => v.indexOf(".spec") === -1)
      .map((v) => this.genTestFile(v));
  }
  genTestFile(filename) {
    console.log("filename:", filename);
    // 生成测试文件名
    const testFileName = this.getTestFileName(filename);
    // 判断此文件是否存在
    if (fs.existsSync(testFileName)) {
      console.log(`${testFileName}测试文件已存在`);
      return;
    }
    const mod = require(filename);
    // 所有产生的代码合并成一个字符长串
    // 也就是断言用的字符串
    let source;
    if (typeof mod === "object") {
      source = Object.keys(mod)
        .map((v) => this.getTestSource(v, path.basename(filename), true))
        .join("\n");
    } else if (typeof mod === "function") {
      // true是因为对象需要解构
      source = this.getTestSource(
        path.basename(filename).replace(".js", ""),
        path.basename(filename)
      );
    }
    fs.writeFileSync(testFileName, source);
  }
  // classFile路径
  getTestSource(methodName, classFile, isClass = false) {
    console.log("getTestSource:", methodName);
    return `
test('${"TEST " + methodName}') ,()=> {
  const ${isClass ? "{" + methodName + "}" : methodName} = require('${
      "../" + classFile
    }')
  const ret = ${methodName}()
  // expect(ret)
  // .toBe('test return')
}
    `;
  }
  // 生成测试文件名
  getTestFileName(filename) {
    // 目录名称
    const dirName = path.dirname(filename);
    // 文件名称
    const baseName = path.basename(filename);
    // 拓展名.js
    const extName = path.extname(filename);
    const testName = baseName.replace(extName, `.spec${extName}`);
    return path.format({
      root: dirName + "/__test__/",
      base: testName,
    });
  }
};
